package com.py.credit.service.impl;

import com.py.credit.common.GatewayUserSingleOnline;
import com.py.credit.common.XypjConstants;
import com.py.credit.common.XypjUserCacheHelper;
import com.py.credit.entity.GatewayUserEntity;
import com.py.credit.service.GatewayAuthenticationService;
import com.py.credit.service.GatewayUserService;
import com.py.framework.core.helper.JWTHelper;
import com.py.framework.core.utils.SerializingUtil;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 对外接口鉴权数据Service实现
 *
 * @author Leegern
 * @date 2018年4月26日
 */
@Service
public class GatewayAuthenticationServiceImpl implements GatewayAuthenticationService {

    @Autowired
    private GatewayUserService gatewayUserService;

    @Override
    public void putUserSessionData(String jdToken, GatewayUserEntity user) {
        // 缓存用户信息
        XypjUserCacheHelper.putUserCache(SerializingUtil.serialize(jdToken), SerializingUtil.serialize(user));

        // 将用户添加到在线列表,用户名会重复,拼接id
        GatewayUserSingleOnline.putInCache(user.getUsername() + user.getId(), jdToken);
    }

    @Override
    public void clearUserSessionData(String jdToken, GatewayUserEntity gatewayUserEntity) {
        if (StringUtils.isNotBlank(jdToken)) {
            // 清空用户信息
            XypjUserCacheHelper.clearUserCache(SerializingUtil.serialize(jdToken));
            // 清除在线用户令牌
            GatewayUserSingleOnline.clearCurrentUserToekn(gatewayUserEntity.getUsername() + gatewayUserEntity.getId(), jdToken);
        }
    }

    @Override
    public GatewayUserEntity getCurrentUserInfo(String token) throws Exception {
        GatewayUserEntity userEntity = null;
        long userId = 0L;
        if (StringUtils.isNotBlank(token)) {
            byte[] bts = XypjUserCacheHelper.getUserFromCache(SerializingUtil.serialize(token));
            if (null == bts || bts.length == XypjConstants.NUMBER_ZERO) {
                userId = this.pickUserId(token);
                if (userId > XypjConstants.NUMBER_ZERO) {
                    Map<String, Object> params = new HashMap<String, Object>();
                    params.put("id", userId);
                    userEntity = gatewayUserService.getUserByTwoPrincipal(params);
                    if (null != userEntity) {
                        XypjUserCacheHelper.putUserCache(SerializingUtil.serialize(token),
                                SerializingUtil.serialize(userEntity));
                    }
                }
            } else {
                userEntity = (GatewayUserEntity) SerializingUtil.deserialize(bts);
            }
        }
        return userEntity;
    }

    @Override
    public void clearUserSessionAllToken(String usernameId) {
        //获取用户tokenList
        List<String> userTokenList = GatewayUserSingleOnline.getUserTokenList(usernameId);

        for (String token : userTokenList
                ) {
            // 清空用户信息
            XypjUserCacheHelper.clearUserCache(SerializingUtil.serialize(token));
        }

        // 清除在线用户令牌
        GatewayUserSingleOnline.clearUserTokens(usernameId);
    }

    @Override
    public void refreshUserSessionAllToken(GatewayUserEntity gatewayUserEntity) {
        //获取用户tokenList
        List<String> userTokenList = GatewayUserSingleOnline.getUserTokenList(gatewayUserEntity.getUsername() + gatewayUserEntity.getId());

        for (String token : userTokenList
                ) {
            // 刷新用户信息
            XypjUserCacheHelper.putUserCache(SerializingUtil.serialize(token), SerializingUtil.serialize(gatewayUserEntity));
        }
    }

    /**
     * 解密用户Id
     *
     * @param jdToken 令牌
     * @return
     * @throws Exception
     */
    private long pickUserId(String jdToken) throws Exception {
        Claims claims = JWTHelper.parseJWT(jdToken);
        long userId = 0L;
        if (null != claims && StringUtils.isNotBlank(claims.getSubject())) {
            userId = Long.parseLong(claims.getId());
        }
        return userId;
    }
}